import { useEffect, useState } from "react";
import styles from "./Collection.module.css";
import { Button, Drawer, Input, Modal, Pagination, Space, Tag } from "antd";
import { useEscape } from "../../../../utils/common/toggleInputFocus";
import React from "react";
import type { KeywordType } from "../../../../utils/domain/keyword";
import {
  addFilter,
  cleanCollectionTypeModal,
  fetchCollectionById,
  fetchCollectionList,
  nextPage,
  removeFilterById,
  updateCollectionTypeModal,
  updateKeyword,
  updateModal,
  updateModalItem,
  updatePageSize,
} from "../../../../utils/store/collectionSlice";
import { useAppDispatch, useAppSelector } from "../../../../utils/store/hooks";
import {
  keywordApi,
  passwordApi,
  Result,
} from "../../../../utils/backend/server";
import { toast } from "../../../../components/Toast/Toast";
import { AxiosError, AxiosResponse } from "axios";
import _ from "lodash";
import { Editor, EditorType } from "../Password/Password";
import { CollectionType } from "../../../CollectionType/CollectionType";
import {
  updateLogin,
  updateRegister,
} from "../../../../utils/store/deviceSlice";
import { SearchOutlined } from "@ant-design/icons";
import { Item } from "./Item/Item";
import { Pop } from "./Pop/Pop";
import { PopFooter } from "./PopFooter/PopFooter";

const calSize = () => {
  const height = Math.ceil((window.innerHeight - 170) / 68);
  const width = Math.ceil(window.innerWidth / 100);
  // return Math.max(height * width, 50);
  return height * width;
};

export const checkAddCollection = (item: KeywordType) => {
  if (item.keyName === "") {
    toast(`please check key name!`);
    throw Error("error");
  }
  if (item.url === "") {
    toast(`please check url!`);
    throw Error("error");
  }
};

export type action = "add" | "modify" | "";
export default () => {
  const collectionData = useAppSelector((state) => state.collection);
  const dispatch = useAppDispatch();
  const mo = useAppSelector((state) => state.collection).modalInfo;
  const [editorData, setEditorData] = useState<EditorType>({
    show: false,
    // url: "",
    pair: [],
    memo: "",
    isEdit: false,
  });
  const collectionTypeModal = useAppSelector(
    (state) => state.collection
  ).collectionTypeModal;
  // .filterList;
  const tags = useAppSelector((state) => state.collection);

  const refresh = () => {
    dispatch(fetchCollectionList());
  };

  const setKeyword = (newKeyword: string) => {
    dispatch(updateKeyword(newKeyword));
    refresh();
  };

  useEscape();

  const cancelModal = () => {
    dispatch(updateModal());
  };
  const resize = _.throttle(
    () => {
      const size = calSize();
      return dispatch(updatePageSize(size));
    },
    2000,
    { leading: true }
  );
  useEffect(() => {
    window.addEventListener("resize", resize);
    return () => {
      window.removeEventListener("resize", resize);
    };
  }, []);

  useEffect(() => {
    if (collectionData.pageSize === -1) resize();
    else refresh();
  }, [collectionData.pageSize]);

  useEffect(() => {
    if (collectionTypeModal.showModal) return;
    if (
      collectionTypeModal.belong === "filter" &&
      collectionTypeModal.id !== -1
    ) {
      dispatch(addFilter([collectionTypeModal]));
      dispatch(cleanCollectionTypeModal());
      dispatch(fetchCollectionList());
    }
  }, [collectionTypeModal.showModal]);

  return (
    <div className={styles.container}>
      <div className={styles.filterSearch}>
        <div className={styles.inputBox}>
          <Input
            addonBefore={<SearchOutlined />}
            className={styles.input}
            value={collectionData.keyword}
            onChange={(e) => setKeyword(e.target.value)}
            autoFocus
          />
          <button
            className={[
              styles.clear,
              collectionData.keyword?.length ? "" : styles.hide,
            ].join(" ")}
            onClick={() => {
              setKeyword("");
            }}
          >
            <img src="/clear.png" alt="clear text img" />
          </button>
        </div>
        <div className={styles.filterBox}>
          <Button
            type="primary"
            icon={<SearchOutlined />}
            onClick={() => {
              dispatch(
                updateCollectionTypeModal({
                  showModal: true,
                  belong: "filter",
                })
              );
            }}
          >
            Filter
            {/* {collectionTypeModal.belong === "filter"
              ? collectionTypeModal.typeName
              : "Filter"} */}
          </Button>
        </div>
      </div>
      <div className={styles.filterTag}>
        {tags.filterList.map((val) => (
          <Tag
            bordered={false}
            closable
            key={val.id}
            onClose={() => {
              dispatch(removeFilterById([val]));
              dispatch(fetchCollectionList());
            }}
          >
            {val.typeName}
          </Tag>
        ))}
      </div>
      <div className={styles.box}>
        {/* 
        {
              id: -1,
              typeName: "",
              description: "",
              createTime: "",
            }
        */}
        <Item
          styles={styles.addEntry}
          entry={{
            id: "",
            typeId: "",
            typeName: "",
            name: String(collectionData.total),
            url: "http://",
            memo: "",
            ranks: 0,
            keyName: "add",
            collectionType: null,
          }}
          direct={true}
          clickHandler={(newItem) => {
            dispatch(
              updateModal({
                open: true,
                type: "add",
                item: newItem,
              })
            );
          }}
        />
        {collectionData.collectionList.map((val, seq) => (
          <Item
            entry={val}
            key={val.id}
            direct={false}
            clickHandler={async (item) => {
              await dispatch(fetchCollectionById(item.id));
            }}
          />
        ))}
      </div>
      <div className={styles.paginationBox}>
        <Pagination
          current={collectionData.pageNo}
          total={collectionData.total}
          pageSize={collectionData.pageSize}
          showSizeChanger={false}
          onChange={(e) => {
            dispatch(nextPage(e));
            dispatch(fetchCollectionList());
          }}
        />
      </div>
      <Drawer
        title="collection types"
        open={collectionTypeModal.showModal}
        onClose={() => {
          dispatch(
            updateCollectionTypeModal({
              showModal: false,
              id: -1,
            })
          );
        }}
        width={720}
        className={styles.drawerStyle}
      >
        <CollectionType
          confirm={(e) => {
            dispatch(
              updateCollectionTypeModal({
                typeName: e.typeName,
                id: e.id,
                showModal: false,
              })
            );
          }}
        />
      </Drawer>
      <Modal
        open={mo.open}
        zIndex={100}
        footer={
          <PopFooter
            type={mo.type}
            onAdd={() => {
              checkAddCollection(mo.item);
              // mo.item.keyName, mo.item.url
              keywordApi
                .addPlaceholder(mo.item)
                .then((res) => {
                  //
                  toast("add: " + res.data.keyName);
                  dispatch(fetchCollectionList());
                  // dispatch(updateModalItem({ isTemp: false }));
                  cancelModal();
                })
                .catch((err: AxiosResponse<Result<any>>) => {
                  toast(err.data.msg);
                });
            }}
            onUpdate={() => {
              checkAddCollection(mo.item);
              // mo.item.id, mo.item.keyName, mo.item.url
              keywordApi
                .updatePlaceholder(mo.item)
                .then((data) => {
                  dispatch(fetchCollectionList());
                  cancelModal();
                })
                .catch((err: AxiosResponse<Result<null>>) => {
                  toast(err.data.msg);
                });
            }}
            onOpen={() => {
              keywordApi.updateRanks(mo.item);
              window.open(mo.item.url);
            }}
          />
        }
        onCancel={async () => {
          if (mo.item.isTemp) {
            await keywordApi.removeKeywordById(mo.item.id);
          }
          cancelModal();
          refresh();
          console.log(mo.item, "cancelModal");
        }}
      >
        <Pop
          type={mo.type}
          hide={cancelModal}
          showLogin={() => dispatch(updateLogin(true))}
          showRegister={() => dispatch(updateRegister(true))}
          showPassword={async () => {
            const res = await passwordApi.fetchPasswords({ id: mo.item.id });
            setEditorData({
              show: true,
              id: mo.item.id,
              pair: res.data.map((val) => ({ ...val, type: "password" })),
              memo: "",
              isEdit: true,
            });
          }}
          del={async () => {
            await keywordApi.removeKeywordByKey(mo.item.keyName);
            // keywordApi.removePlaceholder(mo.item.id).then(() => {
            cancelModal();
            dispatch(fetchCollectionList());
            // });
          }}
        />
      </Modal>
      <Editor data={editorData} reload={() => {}} />
    </div>
  );
};
